package org.ipmsg.core.net;

import org.ipmsg.core.Address;
import org.ipmsg.core.Message;
import org.ipmsg.core.event.DatagramEvent;
import org.ipmsg.core.event.DatagramSendListener;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.Enumeration;
import java.util.Hashtable;
import org.ipmsg.core.Protocol;

public class DatagramSend extends Thread {

    private DatagramSocket udpSocket;
    private Message message;
    private Address address;
    private int wait;
    private int retry;
    private boolean reply;
    private Hashtable listeners;

    public DatagramSend(DatagramSocket argsock, Message argpack, Address argaddr) {
        wait = 3000;
        retry = 3;
        reply = false;
        udpSocket = argsock;
        message = argpack;
        address = argaddr;
        listeners = new Hashtable();
    }

    public void addIPMsgSendListener(DatagramSendListener listener) {
        listeners.put(listener, listener);
    }

    public void removeIPMsgSendListener(DatagramSendListener listener) {
        listeners.remove(listener);
    }

    @Override
    public void run() {
        for (int i = retry; i != 0; i--) {
            send(udpSocket, message, address);
            try {
                sleep(wait);
            } catch (InterruptedException interruptedexception) {
            }
            if (reply) {
                return;
            }
            message.setCommand(message.getCommand() | Protocol.RETRYOPT);
        }

        DatagramEvent sevent = new DatagramEvent(this, message, address);
        synchronized (this) {
            DatagramSendListener listener;
            for (Enumeration em = listeners.elements(); em.hasMoreElements(); listener.sendEvent(sevent)) {
                listener = (DatagramSendListener) em.nextElement();
            }

        }
    }

    public static void send(DatagramSocket argsock, Message argpack, Address argaddr) {
        byte b[] = argpack.getBytes();
        DatagramPacket dpack = new DatagramPacket(b, b.length, argaddr.getInetAddress(), argaddr.getPort());
        try {
            argsock.send(dpack);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public void receiveReply() {
        reply = true;
    }
}
